package com.meituan;

import org.junit.Test;

import java.util.*;

/**
 * 美团第三题
 */
public class test3 {

    private static class UF{

        protected int[] id;

        private int[] used;

        public UF(int n){
            id = new int[n];
            for (int i = 0; i < n; i++) {
                id[i] = i;
            }
            used = new int[n];
        }

        public boolean isConnected(int p, int q) {
            return find(p) == find(q);
        }

        public int find(int p) {
            while(p!=id[p]){
                p = id[p];
            }
            return p;
        }

        public void outId(){
            for(int num : id){
                System.out.print(num + " ");
            }
            System.out.println();
        }

        public int[] getId(){
            return this.id;
        }

        public void union(int p, int q) {
            int pRoot = find(p);
            int qRoot = find(q);

            if(pRoot != qRoot){
                id[pRoot] = qRoot;
            }
        }

        private void cleanUnused(){
            int len = id.length;
            for(int i = 0; i<len; i++){
                if(used[i] == 0) id[i] = -1;
            }
        }
    }

    static HashMap<Integer, PriorityQueue<Integer>> map = new HashMap<>();

    static  PriorityQueue<PriorityQueue<Integer>> queue = new PriorityQueue<>((a,b) -> (a.peek() - b.peek()));

    static HashSet<Integer> Areas = new HashSet<>();

    public static int getAreas(List<int[]> list ){
        int len = list.size();
        UF uf = new UF(10001);
        for(int[] arr : list){
            uf.union(arr[0] , arr[1]);
        }
        HashSet<Integer> counts = new HashSet<>();

        for(Integer i : Areas){
            counts.add(uf.find(i));
            PriorityQueue<Integer> ways = map.get(uf.find(i));
            if(ways == null){
                ways = new PriorityQueue<>();

            }
            ways.add(i);
            map.put(uf.find(i),ways);
        }
        for(Integer integer : map.keySet()){
            queue.add(map.get(integer));
        }
        return counts.size();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        List<int[]> list = new ArrayList<>();
        for(int i = 0; i < n; i++){
            int a = sc.nextInt();
            int b = sc.nextInt();
            list.add(new int[]{a,b});
            //添加到小区列表
            Areas.add(a);
            Areas.add(b);
        }
        sc.close();
        System.out.println(getAreas(list));
        while(!queue.isEmpty()){
            PriorityQueue<Integer> heap= queue.poll();
            while(!heap.isEmpty()){
                System.out.print(heap.poll()+" ");
            }
            System.out.println();
        }
    }


}
